package ar.com.msebuilder;

import java.io.File;

import org.tmatesoft.svn.core.wc.SVNRevision;

import ar.com.msebuilder.MSEBuilder.Operation;
import fr.inria.verveine.extractor.java.VerveineJParser;

public class SVNCheckoutThread extends Thread {

	private static final String MSE_EXTENSION = ".mse";

	private ThreadsManager threadsManager;
	private SVNManager svnManager;
	private String revDestPath;
	private SVNRevision revision;
	private String mseDestPath;
	private boolean deleteSVNFiles;
	private Operation operation;
	
	public SVNCheckoutThread(ThreadsManager threadsManager, SVNManager svnManager, 
			String revDestPath, SVNRevision revision, String mseDestPath, 
			boolean deleteSVNFiles, Operation operation) {
		this.threadsManager = threadsManager;
		this.svnManager = svnManager;
		this.revDestPath = revDestPath;
		this.revision = revision;
		this.mseDestPath = mseDestPath;
		this.deleteSVNFiles = deleteSVNFiles;
		this.operation = operation;
	}
	
	@Override
	public void run() {
		boolean checkoutSuccessful = true;
		switch(operation) {
			case SVNDOWNLOAD:
				// Export a copy of the given revision
				checkoutSuccessful = svnManager.exportRevision(revision, revDestPath);	
				break;
			case MSECREATION:
				// Create the MSE file for the revision downloaded
				createMSEFile(revDestPath);
				break;
			case ALL:
				// Export a copy of the given revision
				checkoutSuccessful = svnManager.exportRevision(revision, revDestPath);	
				if (checkoutSuccessful) {
					// Create the MSE file for the revision downloaded
					createMSEFile(revDestPath);
					// Decrease by 1 the number of running threads
					threadsManager.removeRunningThreads();			
				}
				break;
			
		}
		// If the user chose to delete the SVN files or there was a problem while 
		// doing the checkout then delete the revision's folder and all teh files inside
		if (deleteSVNFiles || !checkoutSuccessful) {
			File svnDir = new File(revDestPath);
			// This if is needed in case there was a problem on the checkout 
			// before the revision's folder was created
			if (svnDir != null) {
				deleteSVNFiles(svnDir);				
			}
		}
		// Decrease by 1 the number of running threads
		threadsManager.removeRunningThreads();			
	}
	
	private void createMSEFile(String path) {
		// A parser for each file MUST be created, otherwise the parser will
		// save the information from every file
		VerveineJParser parser = new VerveineJParser();
		String[] args = { path };
		parser.setOptions(args);
		// Removes the last "/" from the path, if it exists
		path = parseSourceDir(path);
		parser.setOutputFileName(path.substring(path.lastIndexOf(File.separator)+1).
				concat(MSE_EXTENSION));
		parser.parse();
		parser.emitMSE(parseDestDir(mseDestPath) + parser.getOutputFileName());
	}
	
	private String parseSourceDir(String srcDir) {
		if (srcDir.endsWith(File.separator)) {
			srcDir = srcDir.substring(0, srcDir.lastIndexOf(File.separator));
		}
		return srcDir;		
	}
	
	private String parseDestDir(String destDir) {
		if (!destDir.endsWith(File.separator)) {
			destDir = destDir.concat(File.separator);
		}
		return destDir;
	}
	
	private void deleteSVNFiles(File dir) {
		File[] children = dir.listFiles();
		for (File child : children) {
			if(child.isDirectory()) {
				deleteSVNFiles(child);
			} else {
				child.delete();				
			}
		}
		dir.delete();
	}
	
}
